import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_components_web/utils/common.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:http/http.dart' as http;

const tlyric = "tlyric";
const lyric = "lyric";
const lrc = "lrc";
const bgLinearGradient = LinearGradient(
  begin: Alignment.topCenter,
  end: Alignment.bottomCenter,
  colors: [Color.fromRGBO(124, 105, 13, 1), Color.fromRGBO(36, 41, 9, 1)],
);
const playerLineGradient = LinearGradient(
  begin: Alignment.topCenter,
  end: Alignment.bottomCenter,
  colors: [Color.fromRGBO(41, 45, 16, 0.8), Color.fromRGBO(31, 38, 16, 1)],
);
final customBoxShadow = BoxShadow(
  offset: Offset(0, 0),
  color: Color.fromRGBO(41, 45, 16, 0.8),
  spreadRadius: 40.r,
  blurRadius: 30.r,
);
final customBoxShadow2 = BoxShadow(
  offset: Offset(0, 0),
  color: Color.fromRGBO(101, 87, 13, 0.8),
  spreadRadius: 40.r,
  blurRadius: 30.r,
);

class LyricLine {
  final Duration time; // 时间
  final String text; // 原歌词
  final String? translation; // 翻译

  LyricLine(this.time, this.text, {this.translation});
}

class ComMusicPlayer extends StatefulWidget {
  @override
  State<ComMusicPlayer> createState() => _ComMusicPlayerState();
}

class _ComMusicPlayerState extends State<ComMusicPlayer> {
  late List<LyricLine> _lyrics; // 所有歌词
  late Duration _currentTime; // 当前播放时间进度
  late Timer autoScrollTimer; // 自动滚动计时器
  late ScrollController sC;
  late int _currentIndex; // 当前滚动的位置
  late double lyricsHeight; // 默认每一行歌词高度
  late double playerHeight; // 播放器高度
  late bool _isUserScrolling = false; // 用户滚动
  late Timer? _resetAutoScrollTimer; // 重置到自动滚动位置
  late int handlePreScrollIndex; // 预手动滚动
  late Duration reset2AutoScrollDuration; // 重新自动滚动时间
  late double songTitleHeight; // 标题的高音

  @override
  void initState() {
    _lyrics = [];
    _lyrics = [];
    _currentTime = Duration.zero;
    _currentIndex = 0;
    _resetAutoScrollTimer = null;
    sC = ScrollController();
    handlePreScrollIndex = -1;
    reset2AutoScrollDuration = Duration(seconds: 3);
    lyricsHeight = phone ? 70.r : 90.r;
    playerHeight = 70.r;
    songTitleHeight = phone ? 120.r : 150.r;
    // 获取歌词信息
    _fetLyric().then((value) {
      _lyrics = parseLyric(value);
    });
    // 模拟播放歌曲进度
    _simulatePlayback();
    // 监听滚动时间
    _listenMusicPlayer();
    super.initState();
  }

  @override
  void dispose() {
    autoScrollTimer.cancel();
    sC.dispose();
    _resetAutoScrollTimer?.cancel();
    sC.removeListener(_handleScroll);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        padding: EdgeInsets.all(10.r),
        decoration: BoxDecoration(gradient: bgLinearGradient),
        child: Column(
          children: [
            // 标题
            _buildSongTitleBlock(),
            // 歌词
            Expanded(
              child: ListView.builder(
                padding: EdgeInsets.zero,
                controller: sC,
                itemBuilder: (ctx, index) => _buildLyricsItem(index),
                itemCount: _lyrics.length + 2,
              ),
            ),
            // 播放器
            Container(
              width: 1.sw,
              height: playerHeight,
              alignment: Alignment.center,
              decoration: BoxDecoration(
                boxShadow: [customBoxShadow],
                gradient: playerLineGradient,
              ),
              child: Text(
                duration2Str(_currentTime.inMilliseconds),
                style: TextStyle(fontSize: 20.r, color: Colors.white),
              ),
            ),
          ],
        ),
      ),
    );
  }

  // 监听歌词滚动
  _listenMusicPlayer() {
    sC.addListener(_handleScroll);
  }

  // 滚动函数
  _handleScroll() {
    if (sC.position.isScrollingNotifier.value) {
      if (!_isUserScrolling) {
        _isUserScrolling = true;
      }
      if (_isUserScrolling) {
        _currentIndex = -1;
        handlePreScrollIndex =
            ((sC.position.pixels - (lyricsHeight * 0.5)) / lyricsHeight)
                .toInt();
      }
      _resetAutoScrollTimer?.cancel();
      _resetAutoScrollTimer = Timer.periodic(reset2AutoScrollDuration, (timer) {
        _isUserScrolling = false;
      });
    }
  }

  // 获取歌词数据
  List getLyric(String lyricText, {bool isTranslation = false}) {
    const JsonDecoder decoder = JsonDecoder();
    final data = decoder.convert(lyricText);
    String json = "";
    if (isTranslation) {
      json = data[tlyric][lyric];
    } else {
      json = data[lrc][lyric];
    }
    return json.split("\n");
  }

  // 解析歌曲
  List<LyricLine> parseLyric(String lyricText) {
    final lines = getLyric(lyricText, isTranslation: false);
    final tLines = getLyric(lyricText, isTranslation: true);
    final result = <LyricLine>[];
    final tResult = <LyricLine>[];
    final regExp = RegExp(r'\[(\d+):(\d+)\.(\d+)\](.*)');
    for (final line in tLines) {
      final match = regExp.firstMatch(line);
      if (match != null) {
        final minutes = int.parse(match.group(1)!);
        final seconds = int.parse(match.group(2)!);
        final milliseconds = int.parse(match.group(3)!);
        final text = match.group(4)!.trim();
        final time = Duration(
          minutes: minutes,
          seconds: seconds,
          milliseconds: milliseconds,
        );
        tResult.add(LyricLine(time, text));
      }
    }
    for (final line in lines) {
      final match = regExp.firstMatch(line);
      if (match != null) {
        final minutes = int.parse(match.group(1)!);
        final seconds = int.parse(match.group(2)!);
        final milliseconds = int.parse(match.group(3)!);
        final text = match.group(4)!.trim();
        final time = Duration(
          minutes: minutes,
          seconds: seconds,
          milliseconds: milliseconds,
        );
        final translation = tResult.firstWhere(
          (e) => time == e.time,
          orElse: () => LyricLine(Duration(seconds: 999), ""),
        );
        result.add(LyricLine(time, text, translation: translation.text));
      }
    }
    return result;
  }

  // 获取网易云歌词
  Future<String> _fetLyric() async {
    final headers = {'Content-Type': 'application/x-www-form-urlencoded'};
    final request = http.Request(
      'POST',
      Uri.parse('https://music.163.com/weapi/song/lyric'),
    );
    request.bodyFields = {
      'params':
          'H9anojuXjLm/lJ4EHbOSAczu4CFiCbgzMb3W1UmJ3USQlPrWGMeqyAUrhrWC5ZYEHL/WJ91kpEgoYXAW1qOPhkTSGsMu7hF0YFCKAiBpRi7GQ6YOnZFShiC9if0BmPzwhJTQwcYxrvc39xtbMDjtURrb9Mt/ulVjJZ+1NDAiVee0SYHNOLL43BN/dcfcuABv',
      'encSecKey':
          '36df3a3cd82478131680a64509ef9c8cbe0df3ce511db0729d45f4e194594998045f51259cbf9673ff85e6df33ccaf64fa973106492ecc65ec5788194af0e6b6084481838faa7383f082cf19856c7036b27b66103b3b7556f3e2b43a412e6343ccab6bbca856c23f0147adc18ab33def2a3c10c0f599304ee6d5c300cb0c0f47',
    };
    request.headers.addAll(headers);
    http.StreamedResponse response = await request.send();
    if (response.statusCode == 200) {
      return await response.stream.bytesToString();
    } else {
      return "";
    }
  }

  // 模拟播放器
  _simulatePlayback() {
    autoScrollTimer = Timer.periodic(Duration(milliseconds: 100), (timer) {
      _currentTime += Duration(milliseconds: 100);
      setState(() {
        _autoScroll();
      });
    });
  }

  // 自动滚动
  _autoScroll() {
    if (_isUserScrolling) return;
    int newIndex = 0;
    for (int i = newIndex; i < _lyrics.length; i++) {
      if (_currentTime >= _lyrics[i].time) {
        newIndex = i;
      } else {
        break;
      }
    }

    if (newIndex != _currentIndex) {
      _currentIndex = newIndex;
    }
    final double scrollOffset = (newIndex + 0.9) * lyricsHeight;
    sC.animateTo(
      scrollOffset,
      duration: const Duration(milliseconds: 300),
      curve: Curves.easeOut,
    );
  }

  // 手机端
  bool get phone =>
      defaultTargetPlatform == TargetPlatform.android ||
      defaultTargetPlatform == TargetPlatform.iOS;

  // 歌词及翻译
  Widget _buildLyricsItem(int index) {
    if (index == 0 || index == _lyrics.length + 1) {
      return Container(height: (1.sh - playerHeight - songTitleHeight) / 2);
    } else {
      final isSelected =
          index - 1 == _currentIndex || index - 1 == handlePreScrollIndex;
      final selectedColor = isSelected ? Colors.white : Colors.white38;
      final selectedText =
          isSelected ? (phone ? 20.r : 28.r) : (phone ? 14.r : 20.r);
      final bool haveTranslation = _lyrics[index - 1].translation!.isNotEmpty;
      final tStyle = TextStyle(fontSize: selectedText, color: selectedColor);
      final transStyle = TextStyle(
        fontSize: selectedText,
        color: selectedColor,
      );

      final text = AnimatedDefaultTextStyle(
        style: tStyle,
        duration: Duration(milliseconds: 500),
        child: Text(_lyrics[index - 1].text, overflow: TextOverflow.ellipsis),
      );
      final transText = AnimatedDefaultTextStyle(
        duration: Duration(milliseconds: 500),
        style: transStyle,
        child: Text(
          _lyrics[index - 1].translation!,
          overflow: TextOverflow.ellipsis,
        ),
      );

      return Container(
        height: lyricsHeight,
        alignment: Alignment.center,
        child:
            haveTranslation
                ? Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [text, transText],
                )
                : text,
      );
    }
  }

  // 转为分秒
  String duration2Str(int inMilliseconds) {
    final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
      inMilliseconds,
    );
    return "${dateTime.minute.fill0()}:${dateTime.second.fill0()}";
  }

  // 歌曲标题
  _buildSongTitleBlock() {
    return Container(
      alignment: Alignment.center,
      height: songTitleHeight,
      decoration: BoxDecoration(boxShadow: [customBoxShadow2]),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Text(
            "We Don't Talk Anymore",
            style: TextStyle(fontSize: 24.r, color: Colors.white),
          ),
          Text(
            "Charlie Puth / Selena Gomez",
            style: TextStyle(fontSize: 12.r, color: Colors.white38),
          ),
        ],
      ),
    );
  }
}
